const fs = require('fs')
const express = require('express')
const bodyParser = require('body-parser')
const lodash = require('lodash')
const session = require('express-session')
const randomize = require('randomatic')

const app = express()
app.use(bodyParser.urlencoded({extended: true})).use(bodyParser.json())
const path = require('path');
app.use('/static', express.static(path.join(__dirname, 'static')));
app.use(session({
    name: 'thejs.session',
    secret: randomize('aA0', 16),
    resave: false,
    saveUninitialized: false
}))
app.engine('ejs', function (filePath, options, callback) { // define the template engine
    fs.readFile(filePath, (err, content) => {
        if (err) return callback(new Error(err))
        let compiled = lodash.template(content)
        let rendered = compiled({...options})

        return callback(null, rendered)
    })
})
app.set('views', './views')
app.set('view engine', 'ejs')

const ENABLE_MERGE_PATCH = false; // 切换 true 为修复，false 为原始

app.all('/', (req, res) => {
    let data = req.session.data || {language: [], category: []}
    if (req.method == 'POST') {
        if (ENABLE_MERGE_PATCH) {
            // 深拷贝并过滤 __proto__、constructor、prototype 字段
            function safeCopy(obj) {
                if (Array.isArray(obj)) {
                    return obj.map(safeCopy);
                } else if (obj && typeof obj === 'object') {
                    const result = {};
                    for (const key in obj) {
                        if (key === '__proto__' || key === 'constructor' || key === 'prototype') continue;
                        result[key] = safeCopy(obj[key]);
                    }
                    return result;
                }
                return obj;
            }
            const safeBody = safeCopy(req.body);
            data = lodash.merge(data, safeBody);
        } else {
            // 原始有漏洞的合并
            data = lodash.merge(data, req.body)
        }
        req.session.data = data
    }
    
    res.render('index', {
        language: data.language, 
        category: data.category
    })
})

app.listen(3000, () => console.log(`Example app listening on port 3000!`))
